package com.hulman.oms.service;

import com.hulman.oms.bean.*;
import com.hulman.oms.dao.PatrolDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.DateUtil;
import com.hulman.oms.util.OrderUtil;
import com.hulman.oms.util.SubjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author: maxwellens
 */
@Service
public class PatrolService
{
    private static final String PROCESS_KEY = "patrol";

    /**
     * 审核通过
     */
    private static final Integer AUDIT_OK = 1;

    /**
     * 审核不通过
     */
    private static final Integer AUDIT_NG = 2;

    @Autowired
    private PatrolDao patrolDao;
    @Autowired
    private ProcInstService procInstService;
    @Autowired
    private MsgService msgService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private UserService userService;

    public List<Patrol> findPatrols(Map<String, Object> map)
    {
        return patrolDao.findPatrols(map);
    }

    public Integer findPatrolsCount(Map<String, Object> map)
    {
        return patrolDao.findPatrolsCount(map);
    }

    public Result findPatrolsResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = patrolDao.findPatrolsCount(map);
        List<Patrol> data = patrolDao.findPatrols(map);
        return new Result(data, count);
    }

    public Patrol findPatrolById(Integer id)
    {
        return patrolDao.findPatrolById(id);
    }

    public void savePatrol(Patrol patrol)
    {
        if (patrol.getId() != null && patrol.getId() != 0)
        {
            patrolDao.updatePatrol(patrol);
        } else
        {
            patrolDao.insertPatrol(patrol);
        }
    }

    public void deletePatrolById(Integer id)
    {
        patrolDao.deletePatrolById(id);
    }

    public void deletePatrols(int[] ids)
    {
        patrolDao.deletePatrols(ids);
    }

    /**
     * 创建巡检工单
     */
    @Transactional(rollbackFor = Exception.class)
    public void create(Integer shift, String vehicle, String driver)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        //创建工单
        ProcInst procInst = procInstService.startProcess(PROCESS_KEY);
        Patrol patrol = new Patrol();
        patrol.setProcInstId(procInst.getId());
        patrol.setNo(OrderUtil.generate("XJ"));
        patrol.setPatrolById(user.getId());
        patrol.setPatrolByName(user.getName());
        patrol.setArea(user.getArea());
        patrol.setShift(shift);
        patrol.setVehicle(vehicle);
        patrol.setDriver(driver);
        patrol.setStartTime(new Date());
        patrol.setAuditTimes(0);
        patrol.setState(Patrol.STATE_EXECUTING);
        patrolDao.insertPatrol(patrol);
        //生成创建任务
        Task task1 = new Task();
        task1.setProcInstId(procInst.getId());
        task1.setOwnerId(user.getId());
        task1.setOwnerName(user.getName());
        task1.setName(procInst.getStateName());
        task1.setTag(PROCESS_KEY);
        task1.setFormKey(patrol.getId().toString());
        task1.addExtra("工单号", patrol.getNo());
        task1.addExtra("巡检车辆", patrol.getVehicle());
        task1.addExtra("同行司机", patrol.getDriver());
        taskService.createAndCompleteTask(task1);
        //生成巡检任务
        procInst = procInstService.next(procInst.getId());
        Task task2 = new Task();
        task2.setProcInstId(procInst.getId());
        task2.setOwnerId(user.getId());
        task2.setOwnerName(user.getName());
        task2.setName(procInst.getStateName());
        task2.setTag(PROCESS_KEY);
        task2.setFormKey(patrol.getId().toString());
        task2.addExtra("工单号", patrol.getNo());
        task2.addExtra("巡检车辆", patrol.getVehicle());
        task2.addExtra("同行司机", patrol.getDriver());
        taskService.addTask(task2);
        task2.setPath("/pages/patrol/detail?taskId=" + task2.getId());
        //task2.setPage("/patrol-info.html?taskId=" + task2.getId());
        taskService.saveTask(task2);
    }

    /**
     * 暂存工单
     *
     * @param id
     * @param content
     * @param routes
     * @param imgs
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(Integer id, String content, String routes, String imgs)
    {
        Patrol patrol = patrolDao.findPatrolById(id);
        patrol.setContent(content);
        patrol.setRoutes(routes);
        patrol.setImgs(imgs);
        patrolDao.updatePatrol(patrol);
    }

    /**
     * 完成工单
     *
     * @param id      工单ID
     * @param content 巡检内容
     * @param routes  巡检路线
     * @param imgs    现场照片
     */
    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer taskId, Integer id, String content, String routes, String imgs)
    {
        //修改完善工单
        Patrol patrol = patrolDao.findPatrolById(id);
        User patrolDirector = userService.findPatrolDirector(patrol.getArea());
        patrol.setContent(content);
        patrol.setAuditById(patrolDirector.getId());
        patrol.setAuditByName(patrolDirector.getName());
        patrol.setRoutes(routes);
        patrol.setImgs(imgs);
        patrol.setEndTime(new Date());
        patrol.setState(Patrol.STATE_AUDITING);
        patrolDao.updatePatrol(patrol);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
        ProcInst procInst = procInstService.next(patrol.getProcInstId());
        //生成下一个任务（巡检负责人）
        Task task = new Task();
        task.setProcInstId(procInst.getId());
        task.setOwnerId(patrolDirector.getId());
        task.setOwnerName(patrolDirector.getName());
        task.setName(procInst.getStateName());
        task.setTag(PROCESS_KEY);
        task.setFormKey(patrol.getId().toString());
        task.addExtra("工单号", patrol.getNo());
        task.addExtra("巡检内容", patrol.getContent());
        taskService.addTask(task);
        task.setPath("/pages/patrol/detail?taskId=" + task.getId());
        task.setPage("/patrol-info.html?taskId=" + task.getId());
        taskService.saveTask(task);
        msgService.sendMsg(task.toMsg());
    }

    /**
     * 审核工单
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(Integer taskId, Integer id, Integer auditResult, String auditComment)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        Patrol patrol = patrolDao.findPatrolById(id);
        patrol.setAuditById(user.getId());
        patrol.setAuditByName(user.getName());
        patrol.setAuditResult(auditResult);
        patrol.setAuditComment(auditComment);
        patrol.setAuditTime(new Date());
        patrol.setAuditTimes(patrol.getAuditTimes() + 1);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
        if (patrol.getAuditResult() == AUDIT_OK)
        {
            patrol.setState(Patrol.STATE_DOCUMENTED);
            patrolDao.updatePatrol(patrol);
            procInstService.next(patrol.getProcInstId());
            //给巡检人推送审核结果
            Msg msg = new Msg();
            msg.setType(Msg.TYPE_OM);
            msg.setOwnerId(patrol.getPatrolById());
            msg.setOwnerName(patrol.getPatrolByName());
            msg.setTitle("巡检单已审核");
            msg.addItem("巡检内容", patrol.getContent());
            msg.addItem("审核结果", patrol.getAuditResultText());
            msg.addItem("审核意见", patrol.getAuditComment());
            msg.addItem("审核时间", DateUtil.toDate(patrol.getAuditTime()));
            msgService.sendMsg(msg);
        } else if (auditResult == AUDIT_NG)
        {
            procInstService.pre(patrol.getProcInstId());
            patrol.setState(Patrol.STATE_EXECUTING);
            patrolDao.updatePatrol(patrol);
            //创建新的任务
            Task task = new Task();
            task.setProcInstId(patrol.getProcInstId());
            task.setOwnerId(patrol.getPatrolById());
            task.setOwnerName(patrol.getPatrolByName());
            task.setName("审核不通过");
            task.setTag(PROCESS_KEY);
            task.setFormKey(patrol.getId().toString());
            task.addExtra("巡检内容", patrol.getContent());
            task.addExtra("审核意见", patrol.getAuditComment());
            taskService.addTask(task);
            task.setPath("/pages/patrol/detail?taskId=" + task.getId());
            //task.setPage("/patrol-info.html?taskId=" + task.getId());
            taskService.saveTask(task);
            msgService.sendMsg(task.toMsg());
        }
    }

    /**
     * 撤销工单
     *
     * @param id 工单ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void terminate(Integer id)
    {
        //修改工单
        Patrol patrol = patrolDao.findPatrolById(id);
        patrol.setState(Patrol.STATE_TERMINATED);
        patrolDao.updatePatrol(patrol);
        //增加撤销流程信息
        User user = SubjectUtil.getUser();
        Task task = new Task();
        task.setProcInstId(patrol.getProcInstId());
        task.setOwnerId(user.getId());
        task.setOwnerName(user.getName());
        task.setName("撤销工单");
        task.setTag(PROCESS_KEY);
        taskService.createAndCompleteTask(task);
        //终止流程
        procInstService.terminate(patrol.getProcInstId());
    }

    public List<Patrol> findTodayPatrols()
    {
        return patrolDao.findTodayPatrols();
    }

    public List<Patrol> findLatestPatrols()
    {
        return patrolDao.findLatestPatrols();
    }

    /**
     * 近期每天巡检数
     *
     * @return
     */
    public List<NameValue> statDailyPatrols(Integer days)
    {
        return patrolDao.statDailyPatrols(days);
    }

    /**
     * 根据日期获取当天的巡检工作
     *
     * @param date
     * @return
     */
    public String getPatrolContents(Date date)
    {
        Map<String, Object> map = new HashMap<>();
        map.put("startDate", DateUtil.toDate(date));
        map.put("endDate", DateUtil.toDate(date));
        List<Patrol> patrols = findPatrols(map);
        StringBuilder contentBuilder = new StringBuilder();
        for (int i = 0; i < patrols.size(); i++)
        {
            Patrol patrol = patrols.get(i);
            contentBuilder.append(patrol.getContent() + "\n");
        }
        return contentBuilder.toString();
    }

}
